package model.tests;

import static org.junit.Assert.*;

import model.elements.Bullet;
import model.elements.Element2D;
import model.elements.PlayerCharacter;
import model.elements.attributes.Coordinate2D;
import model.elements.behaviours.Weapon;
import model.elements.commands.ElementCommandFactory;
import model.elements.factory.ElementsFactory;
import model.elements.factory.ModelElementsDefaultFactory;
import model.elements.states.movement.MovingDown;
import model.elements.states.weapon.BulletEquipped;
import model.elements.states.weapon.ElementWeaponState;
import model.exceptions.MaxAmmoUsed;
import model.exceptions.ModelExceptions;
import model.exceptions.WeaponCouldNotBePlaced;
import model.map.ElementsMap;

import org.junit.BeforeClass;
import org.junit.Test;

// TODO: Auto-generated Javadoc
/**
 * The Class BulletEquippedTest.
 */
public class BulletEquippedTest
{
	
	/** The bomb equipped test. */
	ElementWeaponState testCannonEquipped;
	
	/** The test map. */
	static ElementsMap testMap = new ElementsMap(10,10);
	
	/** The test factory. */
	static ElementsFactory testFactory = new ModelElementsDefaultFactory();
	
	/** The test player character. */
	PlayerCharacter testPlayerCharacter;

	/**
	 * Sets the up before class.
	 *
	 * @throws Exception the exception
	 */
	@BeforeClass
	public static void setUpBeforeClass() throws Exception {		
		ElementCommandFactory.setup(testMap, testFactory);
	}
	
	/**
	 * Test get weapon.
	 *
	 * @throws ModelExceptions the model exceptions
	 */
	@Test
	public void testGetWeapon() throws ModelExceptions
	{
		testPlayerCharacter = new PlayerCharacter( new Coordinate2D(1,0) );
		
		testCannonEquipped 	= new BulletEquipped( 1, testPlayerCharacter );
		
		Weapon testWeapon = testCannonEquipped.getWeapon( new Coordinate2D(2,0), testFactory );
	
		assertTrue( testWeapon.getClass() == Bullet.class );
		
		((Element2D)testWeapon).update();
		
		assertTrue( testWeapon.getPosition().equals( new Coordinate2D(3,0) ) );		

	}

	/**
	 * Test can use weapon.
	 *
	 * @throws ModelExceptions the model exceptions
	 */
	@Test
	public void testCanUseWeapon() throws ModelExceptions
	{
		testPlayerCharacter = new PlayerCharacter( new Coordinate2D(1,0) );
		
		testCannonEquipped 	= new BulletEquipped( 1, testPlayerCharacter );
		
		testCannonEquipped.getWeapon( new Coordinate2D(2,0), testFactory );
		
		assertFalse( testCannonEquipped.canUseWeapon( new Coordinate2D(2,0) ) );
	}

	/**
	 * Test set weapon ttl multiplier.
	 *
	 * @throws ModelExceptions the model exceptions
	 */
	@Test
	public void testSetWeaponTTLMultiplier() throws ModelExceptions
	{
		testPlayerCharacter = new PlayerCharacter( new Coordinate2D(1,0) );
		
		testCannonEquipped 	= new BulletEquipped( 2, testPlayerCharacter );
		
		Bullet testWeapon1 = (Bullet)testCannonEquipped.getWeapon( testPlayerCharacter.getPosition(), testFactory );
		
		testPlayerCharacter.addCommand( ElementCommandFactory.getElementMove( new MovingDown() ) );
		
		testPlayerCharacter.update();
		
		testCannonEquipped.setWeaponTTLMultiplier( 10.0 );
		
		Bullet testWeapon2 = (Bullet)testCannonEquipped.getWeapon( testPlayerCharacter.getPosition(), testFactory );
		
		assertTrue( testWeapon2.getTTL().getValue() == testWeapon1.getTTL().getValue() );
		
	}
	
	/**
	 * Test max ammo used.
	 *
	 * @throws ModelExceptions the model exceptions
	 */
	@Test (expected = MaxAmmoUsed.class)
	public void testMaxAmmoUsed() throws ModelExceptions {
		
		
		testPlayerCharacter = new PlayerCharacter( new Coordinate2D(1,0) );		
		testCannonEquipped 	= new BulletEquipped( 1, testPlayerCharacter );
		testCannonEquipped.getWeapon( new Coordinate2D(0,0), testFactory );
		testCannonEquipped.getWeapon( new Coordinate2D(1,0), testFactory );
		
	}
	
	/**
	 * Test weapon could not be placed.
	 *
	 * @throws ModelExceptions the model exceptions
	 */
	@Test (expected = WeaponCouldNotBePlaced.class)
	public void testWeaponCouldNotBePlaced() throws ModelExceptions {
		
		testPlayerCharacter = new PlayerCharacter( new Coordinate2D(0,0) );		
		testCannonEquipped 	= new BulletEquipped( 2, testPlayerCharacter );
		testCannonEquipped.getWeapon( new Coordinate2D(0,0), testFactory );
		testCannonEquipped.getWeapon( new Coordinate2D(0,0), testFactory );
		
	}

}
